<?php 

if(class_exists('LsClassInfo', false)){
	return;
}

class LsClassInfo
{
	
	/**
	 * Имя плагина
	 * @var int
	 */
	const CI_PLUGIN = 1;
	
	/**
	 * Имя экшна
	 * @var int
	 */
	const CI_ACTION = 2;
	
	/**
	 * Имя модуля
	 * @var int
	 */
	const CI_MODULE = 4;
	
	/**
	 * Имя сущности
	 * @var int
	 */
	const CI_ENTITY = 8;
	
	/**
	 * Имя маппера
	 * @var int
	 */
	const CI_MAPPER = 16;
	
	/**
	 * Имя метода
	 * @var int
	 */
	const CI_METHOD = 32;
	
	/**
	 * Имя хука
	 * @var int
	 */
	const CI_HOOK = 64;
	
	/**
	 * Имя класс наследования
	 * @var int
	 */
	const CI_INHERIT = 128;
	
	/**
	 * Префикс плагина
	 * @var int
	 */
	const CI_PPREFIX = 8192;
	
	/**
	 * Разобранный класс наследования
	 * @var int
	 */
	const CI_INHERITS = 16384;
	
	/**
	 * Путь к файлу класса
	 * @var int
	 */
	const CI_CLASSPATH = 32768;
	
	/**
	 * Все свойства класса
	 * @var int
	 */
	const CI_ALL = 65535;
	
	/**
	 * Свойства по-умолчанию
	 * CI_ALL ^ (CI_CLASSPATH | CI_INHERITS | CI_PPREFIX)
	 * @var int
	 */
	const CI_DEFAULT = 8191;
	
	/**
	 * Объекты
	 * CI_ACTION | CI_MAPPER | CI_HOOK | CI_PLUGIN | CI_ACTION | CI_MODULE | CI_ENTITY
	 * @var int
	 */
	const CI_OBJECT = 95;
	

	
	
	public static function GetPluginName($oModule) {
		return self::GetClassInfo($oModule, self::CI_PLUGIN, true);
	}

	public static function GetPluginPrefix($oModule) {
		return self::GetClassInfo($oModule, self::CI_PPREFIX, true);
	}

	public static function GetModuleName($oModule) {
		return self::GetClassInfo($oModule, self::CI_MODULE, true);
	}	
	
	public static function GetEntityName($oEntity) {
		return self::GetClassInfo($oEntity, self::CI_ENTITY, true);
	}
	
	public static function GetActionName($oAction) {
		return self::GetClassInfo($oAction, self::CI_ACTION, true);
	}
	
	public static function GetClassInfo($oObject,$iFlag=self::CI_DEFAULT,$bSingle=false){
		$sClassName = is_string($oObject) ? $oObject : get_class($oObject);
		$aResult = array();
		if($iFlag & self::CI_PLUGIN){
			$aResult[self::CI_PLUGIN] = preg_match('/^Plugin([^_]+)/i',$sClassName,$aMatches)
				? $aMatches[1]
				: null
			;
		}
		if($iFlag & self::CI_ACTION){
			$aResult[self::CI_ACTION] = preg_match('/^(?:Plugin[^_]+_|)Action([^_]+)/i',$sClassName,$aMatches)
				? $aMatches[1]
				: null
			;
		}
		if($iFlag & self::CI_MODULE){
			$aResult[self::CI_MODULE] = preg_match('/^(?:Plugin[^_]+_|)Module(?:ORM|)([^_]+)/i',$sClassName,$aMatches)
				? $aMatches[1]
				: null
			;
		}
		if($iFlag & self::CI_ENTITY){
			$aResult[self::CI_ENTITY] = preg_match('/_Entity(?:ORM|)([^_]+)/i',$sClassName,$aMatches)
				? $aMatches[1]
				: null
			;
		}
		if($iFlag & self::CI_MAPPER){
			$aResult[self::CI_MAPPER] = preg_match('/_Mapper(?:ORM|)([^_]+)/i',$sClassName,$aMatches)
				? $aMatches[1]
				: null
			;
		}
		if($iFlag & self::CI_HOOK){
			$aResult[self::CI_HOOK] = preg_match('/^(?:Plugin[^_]+_|)Hook([^_]+)$/i',$sClassName,$aMatches)
				? $aMatches[1]
				: null
			;
		}
		if($iFlag & self::CI_METHOD){
			$sModuleName = isset($aResult[self::CI_MODULE])
				? $aResult[self::CI_MODULE]
				: self::GetClassInfo($sClassName, self::CI_MODULE, true)
			;
			$aResult[self::CI_METHOD] = preg_match('/_([^_]+)$/',$sClassName,$aMatches)
				? ($sModuleName && strtolower($aMatches[1]) == strtolower('module'.$sModuleName)
					? null
					: $aMatches[1]
				)
				: null
			;
		}
		if($iFlag & self::CI_PPREFIX){
			$sPluginName = isset($aResult[self::CI_PLUGIN])
				? $aResult[self::CI_PLUGIN]
				: self::GetClassInfo($sClassName, self::CI_PLUGIN, true)
			;
			$aResult[self::CI_PPREFIX] = $sPluginName
				? "Plugin{$sPluginName}_"
				: ''
			;
		}
		if($iFlag & self::CI_INHERIT){
			$aResult[self::CI_INHERIT] = preg_match('/_Inherits?_(\w+)$/i',$sClassName,$aMatches)
				? $aMatches[1]
				: null
			;
		}
		if($iFlag & self::CI_INHERITS){
			$sInherit = isset($aResult[self::CI_INHERIT])
				? $aResult[self::CI_INHERIT]
				: self::GetClassInfo($sClassName, self::CI_INHERIT, true)
			;
			$aResult[self::CI_INHERITS] = $sInherit
				? self::GetClassInfo(
					$sInherit,
					self::CI_OBJECT,
					false)
				: null
			;
		}
		if($iFlag & self::CI_CLASSPATH){
			$aResult[self::CI_CLASSPATH] = self::GetClassPath($sClassName);
		}
		
		return $bSingle ? array_pop($aResult) : $aResult;
	}
	
	
	public static function GetClassPath($oObject){
		$aInfo = self::GetClassInfo(
			$oObject,
			self::CI_OBJECT
		);
		$sPath = Config::get('path.root.server').'/';
		if($aInfo[self::CI_ENTITY]){
			// Сущность
			if($aInfo[self::CI_PLUGIN]){
				// Сущность модуля плагина
				$sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
					.'/classes/modules/'.strtolower($aInfo[self::CI_MODULE])
					.'/entity/'.$aInfo[self::CI_ENTITY].'.entity.class.php'
				;
			}else{
				// Сущность модуля ядра
				$sPath .= 'classes/modules/'.strtolower($aInfo[self::CI_MODULE])
					.'/entity/'.$aInfo[self::CI_ENTITY].'.entity.class.php'
				;
			}
		}elseif($aInfo[self::CI_MAPPER]){
			// Маппер
			if($aInfo[self::CI_PLUGIN]){
				// Маппер модуля плагина
				$sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
					.'/classes/modules/'.strtolower($aInfo[self::CI_MODULE])
					.'/mapper/'.$aInfo[self::CI_MAPPER].'.mapper.class.php'
				;
			}else{
				// Маппер модуля ядра
				$sPath .= 'classes/modules/'.strtolower($aInfo[self::CI_MODULE])
					.'/mapper/'.$aInfo[self::CI_MAPPER].'.mapper.class.php'
				;
			}
		}elseif($aInfo[self::CI_ACTION]){
			// Экшн
			if($aInfo[self::CI_PLUGIN]){
				// Экшн плагина
				$sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
					.'/classes/actions/Action'.$aInfo[self::CI_ACTION].'.class.php'
				;
			}else{
				// Экшн ядра
				$sPath .= 'classes/actions/Action'
					.$aInfo[self::CI_ACTION].'.class.php'
				;
			}
		}elseif($aInfo[self::CI_MODULE]){
			// Модуль
			if($aInfo[self::CI_PLUGIN]){
				// Модуль плагина
				$sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
					.'/classes/modules/'.strtolower($aInfo[self::CI_MODULE])
					.'/'.$aInfo[self::CI_MODULE].'.class.php';
				;
			}else{
				// Модуль ядра
				$sPath .= 'classes/modules/'.strtolower($aInfo[self::CI_MODULE])
					.'/'.$aInfo[self::CI_MODULE].'.class.php'
				;
				if(!is_file($sPath)){
					$sPath = str_replace('/classes/modules/','/engine/modules/',$sPath);
				}
			}
		}elseif($aInfo[self::CI_HOOK]){
			// Хук
			if($aInfo[self::CI_PLUGIN]){
				// Хук плагина
				$sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
					.'/classes/hooks/Hook'.$aInfo[self::CI_HOOK]
					.'.class.php';
				;
			}else{
				// Хук ядра
				$sPath .= 'classes/hooks/Hook'.$aInfo[self::CI_HOOK].'.class.php';
			}
		}elseif($aInfo[self::CI_PLUGIN]){
			// Плагин
			$sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
				.'/Plugin'.$aInfo[self::CI_PLUGIN]
				.'.class.php';
			;
		}else{
			$sClassName = is_string($oObject) ? $oObject : get_class($oObject);
			$sPath .= 'engine/classes/'.$sClassName.'.class.php';
		}
		return is_file($sPath) ? $sPath : null;
	}
	
	
	public static function GetEntityFullName($entity){
		if(is_object($entity)){
			$class = get_class($entity);
		}else{
			$pp = self::GetClassInfo(
				$entity,
				self::CI_PPREFIX,
				true
			);
			$class = $pp;
			$e = explode('_', $entity);
			if($pp){
				array_shift($e);
			}
			if(count($e) == 1){
				$class .= 'Module'.$e[0].'_Entity'.$e[0];
			}elseif(count($e) == 2){
				$class .= 'Module'.$e[0].'_Entity'.$e[1];
			}else{
				return;
			}
		}
		$ci = self::GetClassInfo(
			$class,
			self::CI_INHERIT | self::CI_ENTITY
		);
		if($ci[self::CI_INHERIT] || !$ci[self::CI_ENTITY]){
			return;
		}
		return Engine::getInstance()->Plugin_GetDelegater('entity', $class);
	}
	
	public static function GetEntityShortName($entity){
		$class = self::GetEntityFullName($entity);
		if(!$class){
			return;
		}
		$ci = self::GetClassInfo(
			$class,
			self::CI_PPREFIX | self::CI_MODULE | self::CI_ENTITY
		);
		return
			$ci[self::CI_PPREFIX]
			.($ci[self::CI_MODULE] != $ci[self::CI_ENTITY] ? $ci[self::CI_MODULE].'_' : '')
			.$ci[self::CI_ENTITY]
		;
	}
	
}

?>